package com.component.amap;

import android.content.Intent;
import android.view.View;

import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.maps2d.model.PolylineOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RidePath;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.RouteSearch.*;
import com.amap.api.services.route.WalkPath;
import com.amap.api.services.route.WalkStep;
import com.component.amap.util.ToastUtil;
import com.component.amap.util.AMapUtil;
import com.housekeeperapp.R;

import com.amap.api.services.route.WalkRouteResult;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import java.util.ArrayList;
import java.util.List;


public class RCTAMapModule extends ReactContextBaseJavaModule implements PoiSearch.OnPoiSearchListener, RouteSearch.OnRouteSearchListener{
    ReactApplicationContext mContext;

    private PoiSearch poiSearch;
    private PoiSearch poiSearch_keywords;
    private RouteSearch routeSearch;
    private RideRouteResult mRideRouteResult;
    private WalkRouteResult mWalkRoutResult;
    private int defaultRadius = 3000;
    private RCTAMapView amapView;

    public RCTAMapModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
        PoiSearch poiSearch = null;
        try {
            poiSearch = new PoiSearch(mContext, null);
            PoiSearch poiSearch_keywords = new PoiSearch(mContext, null);
            RouteSearch mRouteSearch = new RouteSearch(mContext);
            this.poiSearch = poiSearch;
            this.poiSearch_keywords = poiSearch_keywords;
            this.routeSearch = mRouteSearch;
        } catch (AMapException e) {
            throw new RuntimeException(e);
        }


    }

    @Override
    public String getName() {
        return "AMapModule";
    }

    @ReactMethod
    public void setOptions(final int reactTag, final ReadableMap options){
        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
                final RCTAMapView mapView = ((RCTAMapView) mContext.getCurrentActivity().findViewById(reactTag));
                if(options.hasKey("centerCoordinate")) {
                    ReadableMap centerCoordinateMap = options.getMap("centerCoordinate");
                    mapView.setLatLng(new LatLng(centerCoordinateMap.getDouble("latitude"), centerCoordinateMap.getDouble("longitude")));
                }
                if(options.hasKey("zoomLevel")) {
                    double zoomLevel = options.getDouble("zoomLevel");
                    mapView.setZoomLevel(zoomLevel);
                }
            }
        });
    }

    @ReactMethod
    public void setCenterCoordinate(final int reactTag, final ReadableMap coordinate){
        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
                final RCTAMapView mapView = ((RCTAMapView) mContext.getCurrentActivity().findViewById(reactTag));
                mapView.setCenterLocation(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"));
            }
        });
    }

    @ReactMethod
    public void searchPoiByCenterCoordinate(ReadableMap params) {

        String types = "";
        if(params.hasKey("types")) {
            types = params.getString("types");
        }
        String keywords = "";
        if(params.hasKey("keywords")) {
            keywords = params.getString("keywords");
        }

        String city = "";
        if(params.hasKey("city")) {
            city = params.getString("city");
        }

        PoiSearch.Query query = new PoiSearch.Query(keywords, types, city);

        if(params.hasKey("offset")) {
            int offset = params.getInt("offset");
            query.setPageSize(offset);//设置每页最多返回多少条poiitem
        }
        if(params.hasKey("page")) {
            int page = params.getInt("page");
            query.setPageNum(page);//设置查询页码
        }
        poiSearch.setQuery(query);

        if(params.hasKey("coordinate")) {
            ReadableMap coordinateMap = params.getMap("coordinate");
            double latitude = coordinateMap.getDouble("latitude");
            double longitude = coordinateMap.getDouble("longitude");
            int radius = defaultRadius;
            if (params.hasKey("radius")) {
                radius = params.getInt("radius");
            }
            poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(latitude, longitude), radius)); //设置周边搜索的中心点以及半径(单位: 米, 默认3公里)
        }

        poiSearch.setOnPoiSearchListener(this);
        poiSearch.searchPOIAsyn();
    }


    @ReactMethod
    public void searchPoiByKeyswords(ReadableMap params) {

        String types = "";
        if(params.hasKey("types")) {
            types = params.getString("types");
        }
        String keywords = "";
        if(params.hasKey("keywords")) {
            keywords = params.getString("keywords");
        }

        String city = "";
        if(params.hasKey("city")) {
            city = params.getString("city");
        }

        PoiSearch.Query query = new PoiSearch.Query(keywords, types, city);

        if(params.hasKey("offset")) {
            int offset = params.getInt("offset");
            query.setPageSize(offset);//设置每页最多返回多少条poiitem
        }
        if(params.hasKey("page")) {
            int page = params.getInt("page");
            query.setPageNum(page);//设置查询页码
        }

        poiSearch_keywords.setQuery(query);

        poiSearch_keywords.setOnPoiSearchListener(this);
        poiSearch_keywords.searchPOIAsyn();
    }

    // 骑车规划路线
    @ReactMethod
    public void searchRidingRoute(final int reactTag, ReadableMap params) {

        String types = "";
        if(params.hasKey("types")) {
            types = params.getString("types");
        }
        double start_latitude = 0;
        double start_longitude = 0;
        if(params.hasKey("start_latitude") && params.hasKey("start_longitude")) {
            start_latitude = params.getDouble("start_latitude");
            start_longitude = params.getDouble("start_longitude");
        }

        double dest_latitude = 0;
        double dest_longitude = 0;
        if(params.hasKey("dest_latitude") && params.hasKey("dest_longitude")) {
            dest_latitude = params.getDouble("dest_latitude");
            dest_longitude = params.getDouble("dest_longitude");
        }

        LatLonPoint mStartPoint = new LatLonPoint(start_latitude, start_longitude);
        LatLonPoint mEndPoint = new LatLonPoint(dest_latitude, dest_longitude);

        final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(mStartPoint, mEndPoint);
        final RideRouteQuery query = new RideRouteQuery(fromAndTo, RouteSearch.RidingDefault);

        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
                amapView = ((RCTAMapView) mContext.getCurrentActivity().findViewById(reactTag));
//                mapView.setCenterLocation(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"));
                routeSearch.setRouteSearchListener(RCTAMapModule.this);
                routeSearch.calculateRideRouteAsyn(query);
            }
        });

    }

    // 步行规划路线
    @ReactMethod
    public void searchWalkingRoute(final int reactTag, ReadableMap params) {

        String types = "";
        if(params.hasKey("types")) {
            types = params.getString("types");
        }
        double start_latitude = 0;
        double start_longitude = 0;
        if(params.hasKey("start_latitude") && params.hasKey("start_longitude")) {
            start_latitude = params.getDouble("start_latitude");
            start_longitude = params.getDouble("start_longitude");
        }

        double dest_latitude = 0;
        double dest_longitude = 0;
        if(params.hasKey("dest_latitude") && params.hasKey("dest_longitude")) {
            dest_latitude = params.getDouble("dest_latitude");
            dest_longitude = params.getDouble("dest_longitude");
        }

        LatLonPoint mStartPoint = new LatLonPoint(start_latitude, start_longitude);
        LatLonPoint mEndPoint = new LatLonPoint(dest_latitude, dest_longitude);

        final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(mStartPoint, mEndPoint);
        final WalkRouteQuery query = new WalkRouteQuery(fromAndTo, RouteSearch.WalkDefault);

        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
                amapView = ((RCTAMapView) mContext.getCurrentActivity().findViewById(reactTag));
//                mapView.setCenterLocation(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"));
                routeSearch.setRouteSearchListener(RCTAMapModule.this);
                routeSearch.calculateWalkRouteAsyn(query);
            }
        });


    }

    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        List<PoiItem> poiItems;
        WritableMap dataMap = Arguments.createMap();
        if (rCode == 1000) {
            if (result != null && result.getQuery() != null) {// 搜索poi的结果
                    // 取得搜索到的poiitems有多少页
                    poiItems = result.getPois();// 取得第一页的poiitem数据，页数从数字0开始

                    WritableArray array = Arguments.createArray();
                    for (PoiItem poi : poiItems) {
                        WritableMap data = Arguments.createMap();
                        data.putString("uid", poi.getPoiId());
                        data.putString("name", poi.getTitle());
                        data.putString("type", poi.getTypeDes());
                        data.putDouble("longitude", poi.getLatLonPoint().getLongitude());
                        data.putDouble("latitude", poi.getLatLonPoint().getLatitude());
                        data.putString("address", poi.getSnippet());
                        data.putString("tel", poi.getTel());
                        data.putInt("distance", poi.getDistance());
                        data.putString("cityCode", poi.getCityCode());
                        data.putString("cityName", poi.getCityName());
                        data.putString("provinceCode", poi.getProvinceCode());
                        data.putString("provinceName", poi.getProvinceName());
                        data.putString("adCode", poi.getAdCode());
                        data.putString("adName", poi.getAdName());
                        array.pushMap(data);
                    }
                    dataMap.putArray("searchResultList", array);
            }
        }
        else {
            WritableMap error = Arguments.createMap();
            error.putString("code", String.valueOf(rCode));
            dataMap.putMap("error", error);
        }

        mContext
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("amap.onPOISearchDone", dataMap);
    }



    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

    @Override
    public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

    }

    @Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {

    }

    @Override
    public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {
        amapView.getMapView().getMap().clear();// 清理地图上的所有覆盖物
        if (i == 1000) {
            if (walkRouteResult != null && walkRouteResult.getPaths() != null) {
                if (walkRouteResult.getPaths().size() > 0) {

                    mWalkRoutResult = walkRouteResult;
                    final WalkPath walkPath = walkRouteResult.getPaths().get(0);

                    // 获取地图实例
                    AMap aMap = amapView.getMapView().getMap();

                    // 添加起点标记
                    MarkerOptions startMarkerOptions = new MarkerOptions()
                            .position(new LatLng(mWalkRoutResult.getStartPos().getLatitude(), mWalkRoutResult.getStartPos().getLongitude()))
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
                    aMap.addMarker(startMarkerOptions);

                    // 添加终点标记
                    MarkerOptions endMarkerOptions = new MarkerOptions()
                            .position(new LatLng(mWalkRoutResult.getTargetPos().getLatitude(), mWalkRoutResult.getTargetPos().getLongitude()))
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                    aMap.addMarker(endMarkerOptions);

                    // 绘制步行路线
                    List<LatLng> walkRoutePoints = new ArrayList<>();
                    List<WalkStep> walkSteps = walkPath.getSteps();
                    for (WalkStep step : walkSteps) {
                        List<LatLonPoint> latLonPoints = step.getPolyline();
                        for (LatLonPoint point : latLonPoints) {
                            walkRoutePoints.add(new LatLng(point.getLatitude(), point.getLongitude()));
                        }
                    }
                    PolylineOptions polylineOptions = new PolylineOptions()
                            .addAll(walkRoutePoints)
                            .width(10)
                            .color(android.graphics.Color.BLUE);
                    aMap.addPolyline(polylineOptions);

                    // 调整地图视野以显示完整路线
                    aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(
                            AMapUtil.getLatLngBounds(walkRoutePoints), 100
                    ));

//                    mWalkRoutResult = walkRouteResult;
//                    final WalkPath walkPath = walkRouteResult.getPaths()
//                            .get(0);
//                    WalkRouteOverlay walkRouteOverlay = new WalkRouteOverlay(
//                            mContext, amapView.getMapView().getMap(), walkPath,
//                            mWalkRoutResult.getStartPos(),
//                            mWalkRoutResult.getTargetPos());
//                    walkRouteOverlay.removeFromMap();
//                    walkRouteOverlay.addToMap();
//                    walkRouteOverlay.zoomToSpan();
//                    mBottomLayout.setVisibility(View.VISIBLE);
//                    int dis = (int) ridePath.getDistance();
//                    int dur = (int) ridePath.getDuration();
//                    String des = AMapUtil.getFriendlyTime(dur)+"("+AMapUtil.getFriendlyLength(dis)+")";
//                    mRotueTimeDes.setText(des);
//                    mRouteDetailDes.setVisibility(View.GONE);
//                    mBottomLayout.setOnClickListener(new View.OnClickListener() {
//                        @Override
//                        public void onClick(View v) {
//                            Intent intent = new Intent(mContext,
//                                    RideRouteDetailActivity.class);
//                            intent.putExtra("ride_path", ridePath);
//                            intent.putExtra("ride_result",
//                                    mRideRouteResult);
//                            startActivity(intent);
//                        }
//                    });
                } else if (walkRouteResult != null && walkRouteResult.getPaths() == null) {
                    ToastUtil.show(mContext, "对不起，没有搜索到相关数据！");
                }
            } else {
                ToastUtil.show(mContext, "对不起，没有搜索到相关数据！");
            }
        } else {
//            ToastUtil.showerror(mContext, i);
        }
    }

    @Override
    public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {
        amapView.getMapView().getMap().clear();// 清理地图上的所有覆盖物
        if (i == 1000) {
            if (rideRouteResult != null && rideRouteResult.getPaths() != null) {
                if (rideRouteResult.getPaths().size() > 0) {
                    mRideRouteResult = rideRouteResult;
                    final RidePath ridePath = rideRouteResult.getPaths()
                            .get(0);
                    RideRouteOverlay rideRouteOverlay = new RideRouteOverlay(
                            mContext, amapView.getMapView().getMap(), ridePath,
                            mRideRouteResult.getStartPos(),
                            mRideRouteResult.getTargetPos());
                    rideRouteOverlay.removeFromMap();
                    rideRouteOverlay.addToMap();
                    rideRouteOverlay.zoomToSpan();
//                    mBottomLayout.setVisibility(View.VISIBLE);
//                    int dis = (int) ridePath.getDistance();
//                    int dur = (int) ridePath.getDuration();
//                    String des = AMapUtil.getFriendlyTime(dur)+"("+AMapUtil.getFriendlyLength(dis)+")";
//                    mRotueTimeDes.setText(des);
//                    mRouteDetailDes.setVisibility(View.GONE);
//                    mBottomLayout.setOnClickListener(new View.OnClickListener() {
//                        @Override
//                        public void onClick(View v) {
//                            Intent intent = new Intent(mContext,
//                                    RideRouteDetailActivity.class);
//                            intent.putExtra("ride_path", ridePath);
//                            intent.putExtra("ride_result",
//                                    mRideRouteResult);
//                            startActivity(intent);
//                        }
//                    });
                } else if (rideRouteResult != null && rideRouteResult.getPaths() == null) {
                    ToastUtil.show(mContext, "对不起，没有搜索到相关数据！");
                }
            } else {
                ToastUtil.show(mContext, "对不起，没有搜索到相关数据！");
            }
        } else {

//            ToastUtil.showerror(mContext, i);
        }
    }
}
